﻿/// <summary>
/// 
///	Author:		    Gerard Finn
///
///	Student No		X00115840
///
///	Date:			Start Date 	:- 22-03-2014
///	Modified					:- 06-04-2014
/// 
/// File            MakeUIDialog.cs
///   
///	Description		Client Dialog for getting user input this file
///	                contains anything related to input or output
///	                Using static functions in some of these classes
///	                so i dont have to crerate instances of the classes
///	                
///                 Using LocalisationSettings.GetString("BlaBla") this is
///                 over the top at this scale but worth having people used
///                 to using this type of thing as they will need it in a work
///                 enviroment 
///
/// </summary>

using System;
using System.Collections.Generic;

namespace Client
{
    /// <summary>
    /// 
    /// Using an enum so there will be no need to use magic
    /// numbers and that way i can alter this any way i want
    /// 
    /// </summary>
    public enum Selection
    {
        INVALID = -1,
        EXIT,
        VIEWITEMS,
        VIEWSINGLEITEM,
        DELETEITEM,
        ADDITEMNAME,
        ADDITEMNAMEANDDATA,
        MODIFYITEM,
        OTHER
    }
    /// <summary>
    /// 
    ///     Base class for creating user dialog
    ///
    /// </summary>
    public class MakeUIDialog
    {
        private IOScreen start;
        public MakeUIDialog()
        {
            start = new IOScreen();
            Choice = Selection.INVALID;
        }
        public void CreateUI()
        {
            Choice = Selection.INVALID;
            do
            {
                Choice = start.Display();

            } while ( Choice == Selection.INVALID );
        }
        public Selection Choice
        {
            get;
            private set;
        }
    }   // End of class MakeUIDialog

    /// <summary>
    /// 
    /// Class for displaying the start screen to the user
    ///         
    /// </summary>
    public class IOScreen
    {
        public Selection Display()
        {
            ItemData = new List<String>();
            ItemId = "";
            StockData = new StockDetails();

            String input = DisplayBaseScreen();
            ItemData.Clear();

            if (input == "")
            {
                return Selection.INVALID;
            }
            if (input.Equals("X") || input.Equals("x"))
            {
                return Selection.EXIT;
            }
            else
            {
                try
                {
                    return EvaluateInput(Int16.Parse(input));
                }
                catch( Exception e )
                {
                    IOClass.WriteLine(e, LocalisationSettings.GetString("InvalidDataInput"));
                    return Selection.INVALID;
                }
            }
        }
        /// <summary>
        /// 
        ///  Private function for displaying the choices 
        ///  available and obtaining a user selection
        /// 
        /// </summary>
        private static String DisplayBaseScreen()
        {
            IOClass.Clear();
            IOClass.WriteLine(LocalisationSettings.GetString("GetSelectOptionString"));
            IOClass.WriteLine("[1]   " + LocalisationSettings.GetString("GetFullListingString"));         // View full list
            IOClass.WriteLine("[2]   " + LocalisationSettings.GetString("GetSingleIitenString"));         // View single item details
            IOClass.WriteLine("[3]   " + LocalisationSettings.GetString("GetDeleteStockItemString"));     // Delete a single item
            IOClass.WriteLine("[4]   " + LocalisationSettings.GetString("GetAddItemNameString"));         // Add an item name to listing
            IOClass.WriteLine("[5]   " + LocalisationSettings.GetString("GetAddItemNameAndDataString"));  // Add an item name and data to listing
            IOClass.WriteLine("[6]   " + LocalisationSettings.GetString("GetModifyItemDetailsString"));   // Change details of an item
            IOClass.WriteLine("[7]   " + LocalisationSettings.GetString("GetOtherString"));               // ToDo havent thought of this yet
            IOClass.WriteLine("[X]   " + LocalisationSettings.GetString("GetExitString"));                // Get the flock out of here

            //
            // Get a selection from the user 
            // Change this line to get data from another input streem
            //
            return IOClass.ReadLine();
        }
        /// <summary>
        /// 
        ///  Private function for evaluating the user input 
        ///  using int value so it can be expanded
        /// 
        /// </summary>
        private static Selection EvaluateInput(Int16 input)
        {
            switch ( input)
            {
                case 1:
                    return Selection.VIEWITEMS;
                case 2:
                    GetItemId();
                    return Selection.VIEWSINGLEITEM;
                case 3:
                    GetItemId();
                    return Selection.DELETEITEM;
                case 4:
                    GetItemId();
                    return Selection.ADDITEMNAME;
                case 5:
                    AddNameAndData();
                    return Selection.ADDITEMNAMEANDDATA;
                case 6:
                    ModifyNameAndData();
                    return Selection.MODIFYITEM;
                case 7:
                    return Selection.OTHER;
                default:
                    return Selection.INVALID;
            }
        }
        /// <summary>
        /// 
        ///  Public variable containing the name of a DB element
        /// 
        /// </summary>
        public static String ItemId
        {
            get;
            private set;
        }
        /// <summary>
        /// 
        ///  Public element containing the data to change / add
        /// 
        /// </summary>
        public static List<String> ItemData
        {
            get;
            private set;
        }
        /// <summary>
        /// 
        ///  Make a stock data element with things to change
        /// 
        /// </summary>
        public static StockDetails StockData
        {
            get;
            private set;
        }
        /// <summary>
        /// 
        ///  Function for obtaining a product name from user
        /// 
        /// </summary>
        private static void GetItemId()
        {
            IOClass.Write("\n\n" + LocalisationSettings.GetString("GetItemIDString"));
            ItemId = IOClass.ReadLine();
        }
        /// <summary>
        /// 
        ///  Function for obtaining user input related to adding an item
        /// 
        /// </summary>
        private static void AddNameAndData()
        {
            GetItemId();
            ProcessUserSelection currentData = new ProcessUserSelection();

            if (currentData.getSingleItem(ItemId))
            {
                ErrorMessage.Display(LocalisationSettings.GetString("UnableToAddItemString")
                                    + LocalisationSettings.GetString("ItemExists") + ItemId);
                return;
            }
            StockData.ProductIdSymbol = ItemId;
            AddScreen();
        }
        /// <summary>
        /// 
        ///  Function to build the output screen for the add functionality
        /// 
        /// </summary>
        private static void AddScreen()
        {
            String output = "";
            double outDouble = 0.0d;
            int outInt = 0;
            IOClass.Clear();

            // Change the product name 
            output = GetStringData("AddProductNameSymbol", StockData.ProductNameSymbol);
            StockData.ProductNameSymbol = output == "" ? StockData.ProductNameSymbol : output;

            // Change the sales price
            outDouble = GetDoubleData("AddSalesPriceSymbol", StockData.SalesPrice);
            StockData.SalesPrice = outDouble == -1.0d ? StockData.SalesPrice : outDouble;

            // Change the purchace price
            outDouble = GetDoubleData("AddPurchacePriceSymbol", StockData.PurchacePrice);
            StockData.PurchacePrice = outDouble == -1.0d ? StockData.PurchacePrice : outDouble;

            // Change the current stock level
            outInt = GetIntData("AddCurrentStockLevel", StockData.CurrentStockLevel);
            StockData.CurrentStockLevel = outInt == -1 ? StockData.CurrentStockLevel : outInt;

            // Change the current stock level yes / no
            outInt = GetIntData("AddStartingStockLevel", StockData.CurrentStockLevel);
            StockData.CurrentStockLevel = outInt == -1 ? StockData.CurrentStockLevel : outInt;
        }
        /// <summary>
        /// 
        ///  Function for obtaining user input of a name and data of an item
        /// 
        /// </summary>
        private static void ModifyNameAndData()
        {
            GetItemId();
            ProcessUserSelection currentData = new ProcessUserSelection();

            if (!currentData.getSingleItem(ItemId))
            {
                ErrorMessage.Display(LocalisationSettings.GetString("UnableToModifyItemString")
                                    + LocalisationSettings.GetString("NoExistingItem") + ItemId);
                return;
            }
            StockData = currentData.StockData;
            ModifyScreen( );
        }
        /// <summary>
        /// 
        ///  Function to build the output screen
        /// 
        /// </summary>
        private static void ModifyScreen()
        {
            String output = "";
            double outDouble = 0.0d;
            int outInt = 0;
            IOClass.Clear();

            // Change the product name 
            output = GetStringData("ModifyProductNameSymbol", StockData.ProductNameSymbol);
            StockData.ProductNameSymbol = output == "" ? StockData.ProductNameSymbol : output;

            // Change the sales price
            outDouble = GetDoubleData("ModifySalesPriceSymbol", StockData.SalesPrice);
            StockData.SalesPrice = outDouble == -1.0d ? StockData.SalesPrice : outDouble;

            // Change the purchace price
            outDouble = GetDoubleData("ModifyPurchacePriceSymbol", StockData.PurchacePrice);
            StockData.PurchacePrice = outDouble == -1.0d ? StockData.PurchacePrice : outDouble;

            // Change the current stock level
            outInt = GetIntData("ChangeCurrentStockLevel", StockData.CurrentStockLevel);
            StockData.CurrentStockLevel = outInt == -1 ? StockData.CurrentStockLevel : outInt;

            // Change the current stock level yes / no
            outInt = GetIntData("ChangeStartingStockLevel", StockData.CurrentStockLevel);
            StockData.CurrentStockLevel = outInt == -1 ? StockData.CurrentStockLevel : outInt;
        }
        /// <summary>
        /// 
        /// Function to get a valid string from the user
        ///  
        /// Param   :   inputDisplayString  String to display to user
        ///             currentValue        String containing the current element value
        ///             
        /// Returns :   The data input or an empty string
        /// 
        /// </summary>
        private static String GetStringData(String inputDisplayString, String currentValue)
        {
            String input = "";
            IOClass.WriteLine(LocalisationSettings.GetString(inputDisplayString) + "  " + currentValue );
            input = IOClass.ReadLine().ToUpper();

            if (input == "Y")
            {
                IOClass.WriteLine(LocalisationSettings.GetString("EnterNewDetails"));
                return IOClass.ReadLine().ToUpper();
            }
            return "";
        }
        /// <summary>
        /// 
        /// Function to get a valid string from the user
        ///  
        /// Param   :   inputDisplayString  String to display to user
        ///             currentValue        Double containing the current element value
        ///             
        /// Returns :   The data input or -1.0 double
        /// 
        /// </summary>
        private static double GetDoubleData(String inputDisplayString, double currentValue)
        {
            String input = "";

            IOClass.WriteLine(LocalisationSettings.GetString(inputDisplayString) + "  " + currentValue);
            input = IOClass.ReadLine().ToUpper();

            if (input == "Y")
            {
                IOClass.WriteLine(LocalisationSettings.GetString("EnterNewDetails"));
                try
                {
                    input = IOClass.ReadLine();
                    return Double.Parse(input);
                }
                catch (Exception e)
                {
                    IOClass.WriteLine(e, LocalisationSettings.GetString("InvalidDataInput"));
                    return -1.0d;
                }
            }
            return -1.0d;
        }
        /// <summary>
        /// 
        /// Function to get a valid string from the user
        ///  
        /// Param   :   inputDisplayString  String to display to user
        ///             currentValue        int containing the current element value
        ///             
        /// Returns :   The data input parsed to an int or -1 int
        /// 
        /// </summary>
        private static int GetIntData(String inputDisplayString, int currentValue)
        {
            String input = "";

            IOClass.WriteLine(LocalisationSettings.GetString(inputDisplayString) + "  " + currentValue);
            input = IOClass.ReadLine().ToUpper();

            if (input == "Y")
            {
                IOClass.WriteLine(LocalisationSettings.GetString("EnterNewDetails"));
                try
                {
                    input = IOClass.ReadLine();
                    return Int16.Parse(input);
                }
                catch (Exception e)
                {
                    IOClass.WriteLine(e, LocalisationSettings.GetString("InvalidDataInput"));
                    return -1;
                }
            }
            return -1;
        }
    }    // End of class StartScreen
}   // End of namespace
